st/entry: Fix clutter action leak when unsetting icon
The name of the removed action did not match the added one anymore,
effectively "leaking" an action whenever an icon was shown and hidden.
This was primarily affecting the clear button in the shell search.
Fixes: 0bf49afda ("Replace ClutterClickAction with new ClutterClickGesture")
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4095>
Sebastian Keller [Sat, 28 Feb 2026 21:26:15 +0000 (22:26 +0100)]
st/entry: Fix primary/secondary icon leak
_st_entry_set_icon() takes a ref when setting the primary/secondary
icon, but the ref is not removed when unsetting the icon or the entry is
destroyed.
Since clutter_actor_add_child() already adds a ref to the icon, there is
actually no need to manually add another ref. So stop doing that to fix
this leak.
This however also requires that StPasswordEntry takes ownership of its
own icon that it may set or unset multiple times. Since it is initially
floating we need to sink the ref for that.
Sebastian Keller [Fri, 27 Feb 2026 12:22:37 +0000 (13:22 +0100)]
workspaceAnimation: Assign movingWindow before creating window actors
The BaseWorkspaceGroup constructor calls _createWindows(), which uses
_shouldShowWindow() to determine which actors to create for the
animation.
In WorkspaceGroup _shouldShowWindow() this depends on a comparison with
this._movingWindow, which however only gets set after the
BaseWorkspaceGroup constructor has been called.
This was causing the moving window to no longer stick to the screen
when moved between workspaces.
Fixes: 96be47933 ("workspaceAnimation: Split out BaseWorkspaceGroup") Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8992
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4092>
Shivam [Sat, 21 Feb 2026 12:22:35 +0000 (17:52 +0530)]
appDisplay: Refresh folder preview when favorites change
Pinning an app from inside a folder did not refresh the
folder preview. FolderIcon._sync() was only listening
to folder GSettings changes, while pinning updates the
favorites setting instead.
As a result, _sync() was never called and the preview
could show stale icons or remain visible when the folder
became empty.
Fix this by also connecting _sync() to
AppFavorites::changed, ensuring the folder preview
updates correctly when favorites are modified.
Alessandro Bono [Fri, 20 Feb 2026 22:57:14 +0000 (23:57 +0100)]
environment: Use replaceAll()
The replace() function expects two parameters, likely the third one
was ignored. Use replaceAll() to replace all the occurrences, not
just the first one.
Alessandro Bono [Fri, 20 Feb 2026 21:42:03 +0000 (22:42 +0100)]
objectManager: Remove unused function
Introduced with 4b450bab1164b9b1225702238e539201974a68b6, this function
has never been used. Furthermore it is wrong because objectPaths is not
indexed. Just drop it.
Sebastian Keller [Sat, 21 Feb 2026 11:32:26 +0000 (12:32 +0100)]
appDisplay: Consider admin defined folders before creating default ones
The system administrator might have defined some default folders system
wide via dconf default values, so checking for user defined values is
not enough. This restores the condition to also skip creating default
ones if the value is not empty. It still skips the creation of default
folders if the empty value was the result of a user action to allow
users deleting all folders.
Fixes: b0d396c82 ("appDisplay: Only create default folders on the first start") Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/9062
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4087>
search: Do not check for class cancellable state after awaiting
In an async function, after awaiting, the cancelled state for the
class-tracked cancellable may not respect the actual state of the
cancellable that has been used to perform the call.
Cancellable reset API is deprecated for long time and it's quite broken.
In fact if a search provider receives a cancelled event may end up
checking if the cancellable has been cancelled, but this may not be true
anymore after a reset.
Use instead new cancellable instances so that once one is used we can
consider the previous one completed and we can forget about it.
search: Catch async function errors and log them unless cancelled
In case a search function fails, we are not providing clear errors, thus
trace the errors when calling async functions from sync ones and when
catching errors.
Note that at the moment is unlikely to receive any cancelled error here,
since the remote search providers calls handle the error already, but we
still use `logErrorUnlessCancelled` instead of `logError` to be more future
proof or to cover the case in which some extension may throw a cancelled
error.
Jordan Petridis [Mon, 16 Feb 2026 02:06:55 +0000 (04:06 +0200)]
status/volume: Check the stream before accessing it
stream-updated will also get emitted when the stream is unset, and trying
to access it then breaks.
In such case we don't need to update the css class of the indicator as it
will be hidden, and we will get another stream-updated before we show
it again anyway.
main: Call RegisterDisplay once UI has initialized
RegisterDisplay is called to signal that graphics have settled,
which allows GDM to terminate pending greeters and plymouth.
Previously, RegisterSession was used for both recording the login
and terminating greeters. This caused a race condition where the
new user shell was setting up while the greeter was tearing down,
leading to configuration conflicts during the asynchronous handoff.
By splitting into RegisterSession (called early to record login) and
RegisterDisplay (called after graphics settle), the greeter teardown
is delayed until the new session has completed its initial modeset.
Fixes: 32a01330 ("main: Register session with GDM on startup")
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4057>
Florian Müllner [Wed, 4 Feb 2026 13:12:25 +0000 (14:12 +0100)]
swipeTracker: Handle invalid position when finding previous point
Commit 8e29babca8adc677 switched to `findLastIndex()` to find
the previous point, which inadvertently changed what value is
returned for invalid input.
Restore the old fallback value and log a stacktrace, so we can
hopefully track down what causes the invalid input.
Sebastian Keller [Wed, 21 Jan 2026 21:54:39 +0000 (22:54 +0100)]
main: Only call gjs_dumpstack() on warnings from main thread
The mozjs code called by gjs_dumpstack() does not appear to be thread
safe and was sometimes resulting in crashes when triggered by error
messages from threads other than the main thread. And even when not
crashing, such a backtrace can only be misleading since only the main
thread is executing JS code.
revisto [Mon, 22 Dec 2025 21:35:03 +0000 (01:05 +0330)]
status/volume: Snap to 100% when over-amplification is enabled
Sound may be distorted when overamplifying. It is therefore
useful to make it easier for users to select exactly 100%
when allow-volume-above-100-percent is enabled, as that is
the highest non-distorted value.
revisto [Mon, 22 Dec 2025 21:32:32 +0000 (01:02 +0330)]
slider: Add mark snapping support
Add API to add and clear marks, similar to GtkScale. The
slider value will snap to a mark when close to it, making
it easy for the user to position the slider exactly at
the mark's value.
The unsnapped value is still tracked internally, to allow
escaping snap zones when the scroll step is smaller than
the snap threshold.
This is not a good habit anywhere and especially in JS code, I assume
the rationale for this was to ensure that cached instances of the proxy
were cleared, but this did not work properly (as it happened on
finalize), and it would still require [1].
So let's just avoid this and assume that the getters just return what we
expect.
gdm/util: Clear the request if user verifier connection is closed
Similarly to previous commit, in case the user verifier connection is
closed we should just clear the user verifier instance, since starting
from this point is going to be just invalid.
gdm/loginDialog: Reset the greeter proxy on connection closed
If gdm fails to start the display session the greeter proxy we are using
gets disconnected, however since commit 56ea95f2 we are now preserving
the greeter instance, and this will eventually lead to using an instance
of a disconnected proxy.
This eventually implies that after a login failure, we would never get
the `::session-opened` signal that actually triggers the session start.
And thus, even the user has properly authenticated, gdm will stick to
the authentication page.
So, instead of reverting such commit (that isn't wrong per se), consume
the greeter proxy connection `::closed` signal and use it to
re-initialize the greeter instance.
If we use a regular idle watch, any session inhibitors can prevent the
watch from triggering, leading to the break manager to never consider
the break as having been completed until the inhibitor is gone. This
could lead to situations in which the system appears to be stuck with
a dimmed screen.
Also start the idle time when the idle watch is created, otherwise any
previous idle time would count towards it, causing the watch to trigger
early, leaving it inconsistent with the rest of the break manager state.
Florian Müllner [Fri, 31 Oct 2025 17:14:14 +0000 (18:14 +0100)]
js: Use one-shot idle/timeout functions
gjs now provides overrides for GLib's one-shot idle/timeout
functions, so use them to save a bit of code and clearly
indicate that a callback is only invoked once.
Florian Müllner [Fri, 31 Oct 2025 17:13:54 +0000 (18:13 +0100)]
extensions-app: Use one-shot idle/timeout functions
gjs now provides overrides for GLib's one-shot idle/timeout
functions, so use them to save a bit of code and clearly
indicate that a callback is only invoked once.
Jonas Ådahl [Fri, 3 Oct 2025 15:02:37 +0000 (17:02 +0200)]
status/keyboard: Adapt to external source of keyboard layout
This adapts to API changes that allow an external source (e.g. remote
desktop API user) to control the current keyboard layout. This is done
in two ways:
If the external keyboard source sets the keymap as "locked", the
indicator is fixed to the short name of the external source, and will
change the indicator label when the layout index is changed accordingly.
The builtin input sources are not selectable, and the keyboard selection
keybinding is disabled.
If the external keyboard source doesn't set the keymap as "locked",
whenever the current keymap is from an external source, it's indicated
as a non-sensitive but selected input source. Selecting another keyboard
layout overrides the one selected by the external entity.
gdm/util: Set minimum display time for authentication messages
Short messages like "PIN locked" were previously displayed for only
480ms (10 chars × 48ms), making them impossible to read. Ensure all
messages are shown for at least 2 seconds.
Ramez Medhat [Wed, 21 Jan 2026 15:28:22 +0000 (17:28 +0200)]
quickSettingsMenu: Add actor group to focus manager
This allows focus to menu item using the tab key to match the behaviour in other menus.
Closes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8904
Jan200101 [Sun, 25 Jan 2026 21:33:49 +0000 (22:33 +0100)]
shell-app: Improve discrete GPU detection
The original logic only took into account if a GPU is the "Default",
meaning the GPU used during boot, which was intended for Laptops with
Hybrid Graphics.
The new logic uses the new Discrete key to figure out which GPU is the
most appropriate to use in order of:
- the first non-default GPU if it is discrete
- the first discrete GPU if it exists
- the first non-default GPU
Milan Crha [Tue, 13 Jan 2026 16:49:27 +0000 (17:49 +0100)]
endSessionDialog: Remove unused UPGRADE_RESTART dialog data
The gnome-software D-Bus OfflineUpdates API does not distinguish
between offline updates and offline upgrades, thus the UPGRADE_RESTART
dialog data are not used and can be dropped.
Milan Crha [Tue, 13 Jan 2026 13:45:32 +0000 (14:45 +0100)]
endSessionDialog: Switch from PackageKit offline updates API to gnome-software
Let the endSessionDialog depend on gnome-software when deciding whether
any offline updates are scheduled and what to after applying them,
instead of using PackageKit, which is not included in distributions
using rpm-ostree and similar.
Another advantage is rather than implementing similar calls for various
package managers and systems in gnome-shell, these implementations should
go into the gnome-software, which should know about them already.
Sebastian Keller [Sat, 24 Jan 2026 17:15:43 +0000 (18:15 +0100)]
appDisplay: Only create default folders on the first start
If all folders were removed, after a session restart the default folders
would have been recreated again, effectively preventing users from
using the app grid without folders.
Avoid this problem by only creating the default folders if the
folder-children setting has never been modified before.
Sebastian Keller [Wed, 21 Jan 2026 18:50:33 +0000 (19:50 +0100)]
st/spinner-content: Fix CoglTexture leak
Most of the members were getting indirectly freed via the
st_spinner_content_set_actor (spinner, NULL) and the subsequent
st_spinner_content_invalidate () on destruction of the actor or
changing of its content when the spinner is stopped.
The texture however was not freed.
This now frees all members explicitly on finalize.
208 (96 direct, 112 indirect) bytes in 1 blocks are definitely lost in loss record 20,960 of 22,464
at 0x4D37833: g_type_create_instance (gtype.c:1877)
by 0x4D1C186: g_object_new_internal.part.0 (gobject.c:2666)
by 0x4D1E0FA: g_object_new_internal (gobject.c:2982)
by 0x4D1E0FA: g_object_new_valist (gobject.c:3004)
by 0x4D1E488: g_object_new (gobject.c:2479)
by 0x5A8B7CB: _cogl_texture_2d_create_base (cogl-texture-2d.c:84)
by 0x572D668: st_spinner_content_paint_content (st-spinner-content.c:175)
by 0x50D2C07: clutter_actor_paint_node (clutter-actor.c:3471)
by 0x50D2C07: clutter_actor_continue_paint (clutter-actor.c:3726)
by 0x511D4F9: clutter_paint_node_paint (clutter-paint-node.c:867)
by 0x50D9717: clutter_actor_paint (clutter-actor.c:3670)
by 0x574199A: st_viewport_paint (st-viewport.c:483)
by 0x50D2C42: clutter_actor_continue_paint (clutter-actor.c:3728)
by 0x511D4F9: clutter_paint_node_paint (clutter-paint-node.c:867)
Carlos Garnacho [Wed, 8 Oct 2025 17:11:37 +0000 (19:11 +0200)]
panel: Use click gesture to trigger window dragging from panel
This gesture is set up on the target phase, in order to ensure only button
presses on the panel itself (and not actors within it) are handled as window
drags.